#ifndef ANIMATION_MEMU_H
#define ANIMATION_MEMU_H

#ifndef OLED_FPS
#define OLED_FPS 60
#endif

#include <U8g2lib.h>

#define MASS 0.6
#define DAMPING 4.5
#define SPRING_CONSTANT 25
#define BOOST 3
#define MAX_BOUNCE 3 
#define PAGE_MAX_LINES 7
// #define INITIAL_V 0

char* connecting_menu[]{
    "WIFI Connecting ...",
    "SSID: ",
    NULL,
    NULL,
    "\\END"
};

char* connecting_result[]{
    "TEST1",
    "TEST1",
    "TEST1",
    "\\END"
};

char* state_menu[4]{
    NULL,
    NULL,
    NULL,
    "\\END"
};

// 弹簧阻尼模型的递推实现
float step_f(float time_step, float mass, float c, float k, float * fvx){
    return k * fvx[2] - c * fvx[1];
} 
float step_v(float time_step, float mass, float c, float k, float * fvx){
    return fvx[1] + ((fvx[0] / mass) * time_step);
} 
float step_x(float time_step, float mass, float c, float k, float * fvx){
    return fvx[2] - (fvx[1] * time_step);
} 

// 渲染单页内容，不刷新屏幕
void render_page(U8G2* u8g2, char* page[], int x, int y){
    for(int i = 0; i < PAGE_MAX_LINES; i++){
        if(page[i] == "\\END"){break;}
        if(page[i] == NULL){continue;}
        if (i == 0){ u8g2->drawStr(x, y+10, page[i]);}  // 第一行间隔稍微宽一点
        else if (i == 1){ u8g2->drawStr(x, y+(14*i)+10, page[i]);}  // 第一行间隔稍微宽一点
        else {u8g2->drawStr(x, y+(10*i)+14, page[i]);}
    }
}

// 自动换行打印，包含了换行符以及过长的消息
void u8g2print_auto_newline(U8G2* u8g2, char* income_str, uint8_t maxlen, uint8_t y, uint8_t x){
    char tempLine[31];
    uint8_t line_now = 0;
    if(maxlen > 20){maxlen = 20;}
    for(int i=0;i<255;i++){
        if(income_str[i]!='\n' && income_str[i]!='\r' && income_str[i]!='\0' && line_now < maxlen){
            tempLine[line_now] = income_str[i];
            line_now ++;
        }else{
            if(income_str[i]=='\n' || income_str[i]=='\r'){
                tempLine[line_now + 1] = '\0';
                u8g2->drawStr(x, y, tempLine);
                y = y + 10;
                line_now = 0;
            }else if (income_str[i]=='\0'){
                tempLine[line_now] = '\0';
                u8g2->drawStr(x, y, tempLine);
                break;
            }else if (line_now >= maxlen){
                tempLine[line_now+1] = '\0';
                u8g2->drawStr(x, y, tempLine);
                y = y + 10;
                line_now = 0;
                tempLine[line_now] = income_str[i];
                line_now ++;
            }
        }
    }
}

// 渲染两个页面切换的弹簧效果，阻塞式
void change_page(U8G2* u8g2, char* page1[], char* page2[], uint16_t max_time=500){
    int frames = max_time * OLED_FPS / 1000;
    int delay_ms = 1000 / OLED_FPS;
    uint8_t bounce = 0;
    float time_step = 1. / OLED_FPS;
    float _fvx[3] = {0., 0., 128.};
    float last_x = 0.;
    for(int i = 0; i < frames && bounce < MAX_BOUNCE; i++){
        // 更新模型
        for(int i = 0; i < BOOST; i++){
            _fvx[0] = step_f(time_step, MASS, DAMPING, SPRING_CONSTANT, _fvx);
            _fvx[1] = step_v(time_step, MASS, DAMPING, SPRING_CONSTANT, _fvx);
            _fvx[2] = step_x(time_step, MASS, DAMPING, SPRING_CONSTANT, _fvx);
        }
        // 统计回弹次数
        if(last_x * _fvx[2] < 0) {bounce ++ ;}
        last_x = _fvx[2];
        u8g2->clearBuffer();
        render_page(u8g2, page1, 128-_fvx[2], 0);
        render_page(u8g2, page2, -_fvx[2], 0);
        u8g2->sendBuffer();
        delay(delay_ms);
        // Serial.printf("%d\t%f\t%f\t%F\n", i, _fvx[0], _fvx[1], _fvx[2]);
    }
    render_page(u8g2, page2, 0, 0);
    u8g2->sendBuffer();
}

#endif